/**
 * 
 */
package de.hft_stuttgart.dsa.ctt.reader;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import de.hft_stuttgart.dsa.ctt.model.Course;
import de.hft_stuttgart.dsa.ctt.model.Curricula;
import de.hft_stuttgart.dsa.ctt.model.Curriculum;
import de.hft_stuttgart.dsa.ctt.model.Period;
import de.hft_stuttgart.dsa.ctt.model.ProblemInstance;
import de.hft_stuttgart.dsa.ctt.model.Room;
import de.hft_stuttgart.dsa.ctt.model.UnavailabilityConstraint;

/**
 * @author Ali Yuruz
 */
public class DatasetReader {
	private enum CURRENTPARSELINE {
		DEFINITION, COURSES, ROOMS, CURRICULA, UNAVAILABILITY_CONSTRAINTS
	}

	private Enum<CURRENTPARSELINE> currentParseLine = CURRENTPARSELINE.DEFINITION;
	private ProblemInstance problemInstance;
	private HashMap<String, Course> courseMap;
	private Curricula curricula;
	private ArrayList<Room> rooms;
	private ArrayList<Period> periods;
	private final String datasetPath = "Instances/";
	public static final String DATASET1 = "comp01.ctt";
	public static final String DATASET2 = "comp02.ctt";
	public static final String DATASET3 = "comp03.ctt";
	public static final String DATASET4 = "comp04.ctt";
	public static final String DATASET5 = "comp05.ctt";
	public static final String DATASET6 = "comp06.ctt";
	public static final String DATASET7 = "comp07.ctt";
	public static final String DATASET8 = "comp08.ctt";
	public static final String DATASET9 = "comp09.ctt";
	public static final String DATASET10 = "comp10.ctt";
	public static final String DATASET11 = "comp11.ctt";
	public static final String DATASET12 = "comp12.ctt";
	public static final String DATASET13 = "comp13.ctt";
	public static final String DATASET14 = "comp14.ctt";
	public static final String DATASET15 = "comp15.ctt";
	public static final String DATASET16 = "comp16.ctt";
	public static final String DATASET17 = "comp17.ctt";
	public static final String DATASET18 = "comp18.ctt";
	public static final String DATASET19 = "comp19.ctt";
	public static final String DATASET20 = "comp20.ctt";
	public static final String DATASET21 = "comp21.ctt";
	public static final String DDS1 = "DDS1.ctt";

	/**
	 * 
	 */
	public ProblemInstance readDataset(String dataset) {
		problemInstance = new ProblemInstance();
		courseMap = new HashMap<String, Course>();
		curricula = new Curricula();
		rooms = new ArrayList<Room>();
		periods = new ArrayList<Period>();

		String filePath = datasetPath + dataset;
		try {
			BufferedReader inputStream = new BufferedReader(new FileReader(filePath));
			String line;
			while ((line = inputStream.readLine()) != null) {
				parseLine(line);
			}
			problemInstance.setRooms(this.rooms);
			problemInstance.setCurricula(this.curricula);
			calculatePeriods();
			problemInstance.setPeriods(this.periods);
			problemInstance.setAllCourses(this.courseMap);

		} catch (IOException e) {
			e.printStackTrace();
		}
		return problemInstance;
	}

	private void calculatePeriods() {
		for (int i = 0; i < problemInstance.getDays(); i++) {
			for (int j = 0; j < problemInstance.getPeriodsPerDay(); j++) {
				// periods.add(new
				// Period(Period.getCalculatedPeriod(problemInstance.getDays(),
				// j, i)));
				periods.add(new Period(Period.getCalculatedPeriod(problemInstance.getPeriodsPerDay(), j, i)));
			}
		}
	}

	private void parseLine(String line) {
		if (line.length() == 0)
			return;
		if (line.trim().equals("COURSES:")) {
			currentParseLine = CURRENTPARSELINE.COURSES;
			return;
		} else if (line.trim().equals("ROOMS:")) {
			currentParseLine = CURRENTPARSELINE.ROOMS;
			return;
		} else if (line.trim().equals("CURRICULA:")) {
			currentParseLine = CURRENTPARSELINE.CURRICULA;
			return;
		} else if (line.trim().equals("UNAVAILABILITY_CONSTRAINTS:")) {
			currentParseLine = CURRENTPARSELINE.UNAVAILABILITY_CONSTRAINTS;
			return;
		} else if (line.trim().equals("END.")) {

			return;
		} else {
			if (currentParseLine == CURRENTPARSELINE.DEFINITION) {
				String[] lineElements = line.split(" ");
				if (line.startsWith("Name")) {
					this.problemInstance.setName(lineElements[1]);
				} else if (line.startsWith("Courses")) {
					this.problemInstance.setNumberOfCourse(Integer.parseInt(lineElements[1]));
				} else if (line.startsWith("Rooms")) {
					this.problemInstance.setNumberOfRooms(Integer.parseInt(lineElements[1]));
				} else if (line.startsWith("Days")) {
					this.problemInstance.setDays(Integer.parseInt(lineElements[1]));
				} else if (line.startsWith("Periods_per_day")) {
					this.problemInstance.setPeriodsPerDay(Integer.parseInt(lineElements[1]));
				} else if (line.startsWith("Curricula")) {
					this.problemInstance.setNumberOfCurricula(Integer.parseInt(lineElements[1]));
				} else if (line.startsWith("Constraints")) {
					this.problemInstance.setNumberOfConstraints(Integer.parseInt(lineElements[1]));
				}

			} else if (currentParseLine == CURRENTPARSELINE.COURSES) {
				Course course = new Course(line);
				courseMap.put(course.getCourseId(), course);
			} else if (currentParseLine == CURRENTPARSELINE.ROOMS) {
				this.rooms.add(new Room(line));
			} else if (currentParseLine == CURRENTPARSELINE.CURRICULA) {
				curricula.addCurriculum(new Curriculum(line, courseMap));
			} else if (currentParseLine == CURRENTPARSELINE.UNAVAILABILITY_CONSTRAINTS) {
				UnavailabilityConstraint uConstraint = new UnavailabilityConstraint(line);
				courseMap.get(uConstraint.getCourseId()).addUnavailabilityConstraint(uConstraint);
			}
		}

	}
}
